#include "Protocol.hpp"
#include "Sock.hpp"
#include <pthread.h>
void Usage(string proc){
  std::cout << "Usage" << "\n\t" << proc << " port " << std::endl;
}

void* HandlerRequest(void* args){
  pthread_detach(pthread_self());
  std::cout << "service begin" << std::endl;
  int sock = *(int*)args;
  delete (int*)args;
  // 1.Method1 Read request
  // request_t req;
  // memset(&req, 0, sizeof(req));
  // ssize_t s = read(sock, &req, sizeof(req));
  // std::cout << "get a request, request size = " << sizeof(req) << std::endl;
  // std::cout << s << " " << req.x << req.op << req.y << std::endl;

  //1.Method2 ReadRequest
  char buffer[1024] = {0};
  ssize_t s = read(sock, buffer, sizeof(buffer) - 1);
  buffer[s] = 0;
  if (s > 0){
    request_t req;
    DeserializeRequest(buffer, req);
    // Read full request success 
    // 2.prase request 
    std::cout << "prase request" << std::endl;
    response_t resp{0 , 0};
    switch (req.op){
      case '+':
        resp.result = req.x + req.y;
        break;
      case '/':
        if (req.y == 0) resp.sign = 1;
        else resp.result = req.x / req.y;
        break;
      default:
        resp.sign = 3; // request method errno
        break;
    }
    // send response
    std::string json_string = SerializeResponse(resp);
    write(sock, json_string.c_str(), json_string.size());
    std::cout << "return response successs" << std::endl;
  }
  // close connection socket
  close(sock);
  return nullptr;
}

int main(int argc, char* argv[]){
  if (argc != 2){
    Usage(argv[0]);
    return (-1);
  }
  uint16_t port = atoi(argv[1]);
  int listen_sock = Sock::Socket();
  Sock::Bind(listen_sock, port);
  Sock::Listen(listen_sock);
  for ( ; ; ){
    int sock = Sock::Accept(listen_sock);
    if (sock > 0){
      pthread_t tid;
      int* psock = new int(sock);
      pthread_create(&tid, nullptr, HandlerRequest, (void*)psock);
    }
  }
}
